package com.bookmanger.server.controller;

import com.bookmanger.common.properties.JWTProperties;
import com.bookmanger.common.result.Result;
import com.bookmanger.common.utils.JwtUtil;
import com.bookmanger.pojo.DTO.CheckInfoDTO;
import com.bookmanger.pojo.DTO.UserRegisterDTO;
import com.bookmanger.pojo.Entity.AdminEntity;
import com.bookmanger.pojo.Entity.Reader;
import com.bookmanger.pojo.VO.AdminLoginVO;
import com.bookmanger.pojo.VO.ReaderLoginVO;
import com.bookmanger.server.service.EmailService;
import com.bookmanger.server.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {
    @Autowired
    private UserService userService;

    @Autowired
    private EmailService emailService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private JWTProperties jwtProperties;

    //用户登录，identity：1是读者，2是管理员
    @PostMapping("/login/reader")
    public Result login(String username, String password) {
        Reader reader = userService.loginReader(username, password);
        if (reader == null) {
            return Result.error("用户名或密码错误");
        } else {
            Map<String, Object> map = new HashMap<>();
            map.put("username", username);
            map.put("id", reader.getId());
            // 使用JwtUtil.createJWT方法生成token
            String token = JwtUtil.createJWT(
                    jwtProperties.getSecretKey(),
                    jwtProperties.getTtl(),
                    map);
            //将登陆成功的username和token存入redis
            ValueOperations ops = stringRedisTemplate.opsForValue();
            ops.set(username, token, 24, TimeUnit.HOURS);
            ReaderLoginVO readerLoginVO = ReaderLoginVO.builder()
                    .id(reader.getId())
                    .readerNumber(reader.getReaderNumber())
                    .name(reader.getName())
                    .department(reader.getDepartment())
                    .major(reader.getMajor())
                    .grade(reader.getGrade())
                    .phoneNumber(reader.getPhoneNumber())
                    .email(reader.getEmail())
                    .gender(reader.getGender())
                    .typeId(reader.getTypeId())
                    .status(reader.getStatus())
                    .token(token)
                    .build();
            return Result.success(readerLoginVO);
        }
    }

    @PostMapping("/login/admin")
    public Result loginAdmin(String username, String password) {
        AdminEntity adminEntity = userService.loginAdmin(username, password);
        if (adminEntity == null) {
            return Result.error("用户名或密码错误");
        } else {
            Map<String, Object> map = new HashMap<>();
            map.put("username", username);
            map.put("id", adminEntity.getId());
            // 使用JwtUtil.createJWT方法生成token
            String token = JwtUtil.createJWT(
                    jwtProperties.getSecretKey(),
                    jwtProperties.getTtl(),
                    map);
            //将登陆成功的username和token存入redis
            ValueOperations ops = stringRedisTemplate.opsForValue();
            ops.set(username, token, 24, TimeUnit.HOURS);
            AdminLoginVO adminLoginVO = AdminLoginVO.builder()
                    .id(adminEntity.getId())
                    .account(adminEntity.getAccount())
                    .name(adminEntity.getName())
                    .gender(adminEntity.getGender())
                    .age(adminEntity.getAge())
                    .title(adminEntity.getTitle())
                    .type(adminEntity.getType())
                    .token(token)
                    .build();
            return Result.success(adminLoginVO);
        }
    }

    @PostMapping("/sendEmailCode")
    public Result sendEmailCode(@RequestParam String email) {

        // 验证邮箱格式
        if (!email.matches("^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$")) {
            return Result.error("邮箱格式不正确!");
        }

        boolean sent = emailService.sendEmailCode(email);
        if (sent) {
            return Result.success("验证码已发送!");
        } else {
            return Result.error("验证码发送失败!");
        }
    }
    @PostMapping("/register")
    public Result registerByEmail(@RequestBody UserRegisterDTO userRegisterDTO) {
        String email = userRegisterDTO.getEmail();
        String phoneNumber = userRegisterDTO.getPhoneNumber();
        String readerNumber = userRegisterDTO.getReaderNumber();
        String code = userRegisterDTO.getCode();
        CheckInfoDTO checkInfoDTOEmail = CheckInfoDTO.builder()
                .info(email)
                .type("email")
                .build();
        CheckInfoDTO checkInfoDTOPhone = CheckInfoDTO.builder()
                .info(phoneNumber)
                .type("phone_number")
                .build();
        CheckInfoDTO checkInfoDTOReaderNumber = CheckInfoDTO.builder()
                .info(readerNumber)
                .type("reader_number")
                .build();
        checkInfo(checkInfoDTOEmail);
        checkInfo(checkInfoDTOPhone);
        checkInfo(checkInfoDTOReaderNumber);
        // 验证邮箱格式
        if (!email.matches("^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$")) {
            return Result.error("邮箱格式不正确!");
        }

        // 验证验证码
        String cachedCode = stringRedisTemplate.opsForValue().get("email:code:" + email);
        if (cachedCode == null || !cachedCode.equals(code)) {
            log.info(cachedCode);
            return Result.error("验证码不正确或已过期!");
        }

        try {
            // 注册用户
            boolean registered = userService.registerByEmail(userRegisterDTO);

            if (registered) {
                return Result.success("注册成功!");
            } else {
                return Result.success("注册失败!");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return Result.error("注册失败!");
        }
    }

    @PostMapping("/checkInfo")
    public Result checkInfo(@RequestBody CheckInfoDTO checkInfoDTO){
        userService.checkInfo(checkInfoDTO);
        return Result.success("信息验证成功!");
    }

}